/* eslint-disable camelcase */

const ASSETS_TYPE = ['img', 'css', 'script', 'link', 'audio', 'video'];

// 获取资源的类型
export function getResType(url) {
  const resTypeResult = /[^?%&=#]+\.(\w+)/.exec(url) || [];
  const resType = resTypeResult[1];
  return resType || '';
}

class AssetSpeed {
  constructor() {
    this.init();
  }

  ErrImgList = []; // 错误图片收集

  currentResPosition = 0; // 当前上报的资源的长度

  init() {
    this.initSuccLogCollect();
    this.initErrLogCollect();
    // 满了就清零
    performance.onresourcetimingbufferfull = () => {
      this.currentResPosition = 0;
      performance.clearResourceTimings();
    };
  }

  // 收集静态资源加载成功的日志
  initSuccLogCollect() {
    const resType = 'resource';
    this.reportSuccLog(performance.getEntriesByType(resType));

    if (typeof window.PerformanceObserver === 'function') {
      const observer = new window.PerformanceObserver((list) => {
        this.reportSuccLog(list.getEntries());
      });
      observer.observe({ entryTypes: [resType] });
    } else {
      // 不支持动态监听，则定时获取资源，并且过滤掉已经上报的部分
      setInterval(() => {
        const allEntries = performance.getEntriesByType(resType);
        const currentEntries = allEntries.slice(this.currentResPosition);
        this.currentResPosition = currentEntries.length;
        this.reportSuccLog(currentEntries);
      }, 3000);
    }
  }

  // 收集静态资源加载错误的日志
  initErrLogCollect() {
    window.document.addEventListener(
      'error',
      (event) => {
        if (!event || !event.target || !event.srcElement) {
          return;
        }
        const target = event.target || event.srcElement;
        const url = target.src || target.href;

        // 发生错误的图片存起来，因为错误的也会放在 entries 中，用来过滤
        if (target.nodeName === 'IMG') {
          this.ErrImgList.push(url);
        }
        // 将错误上报到资源测速
        if (url) {
          const logErrData = {
            url,
            method: 'get',
            pageUrl: window.location.href,
            resType: getResType(url),
          };
          this.reportLog(logErrData);
        }
      },
      true
    );
  }

  reportSuccLog(entries) {
    setTimeout(() => {
      entries.forEach((entry) => {
        const { initiatorType, name } = entry;

        //   错误的图片不上报
        if (this.ErrImgList.indexOf(name) > -1) {
          return;
        }
        // 只收集静态资源
        if (ASSETS_TYPE.indexOf(initiatorType) > -1) {
          const pageUrl = window.location.href;
          const {
            domainLookupStart,
            domainLookupEnd,
            connectStart,
            connectEnd,
            requestStart,
            responseStart,
            responseEnd,
            duration,
          } = entry;
          const speedData = {
            url: name,
            pageUrl,
            domainLookupStart,
            domainLookupEnd,
            connectStart,
            connectEnd,
            requestStart,
            responseStart,
            responseEnd,
            duration,
          };
          this.reportLog(speedData);
        }
      });
    }, 100);
  }

  reportLog() {
    //...
  }
}

export default AssetSpeed;
